//
//  IVCSSDK.m
//  ivcs_ios_demo
//
//  Created by zealcomm user on 2020/10/21.
//  Copyright © 2020 zealcomm user. All rights reserved.
//


#import <IVCS/Constant.h>
#import <IVCS/IRTCSDK.h>
#import <IVCS/CCSClient.h>
#import "IvcsCustomer.h"
#import "IvcsCustomerDelegate.h"
#import <IVCS/API.h>
#import <IVCS/MyCcsClientMessageDelegate.h>
#import <IRTC/IRTCMTLVideoView.h>

static NSString *ivcsSDKErrorDomain = @"zealcomm.ivcs";

@interface IvcsCustomer()<IvcsCustomerDelegate , IRTCSDKDelegate>

// 保存用户的登录信息
@property(strong , nonatomic)ZcoModelUserInfo *zcoModelUserInfo;

// ccs socketIo client
@property(strong,nonatomic)CCSClient *ccsClient;

//irtc sdk
@property(strong,nonatomic)IRTCSDK *irtcSDK;

// default webrtc stream setting parameter
@property(strong,nonatomic)MediaStreamSettingOptions *mediaOptions;

// zms roomn token
@property(copy,nonatomic)NSString *roomToken;

@property(copy , nonatomic)NSString *baseUrl;

@property(strong , nonatomic)NSMutableDictionary *labelAndStreams;

@property(copy , nonatomic)NSString *localStreamLabel ;

@property(strong, nonatomic) IRTCLocalStream *localStream;

@property (nonatomic ,strong)NSDictionary *mediaDic;

@end

@implementation IvcsCustomer

relizeSingleInstance(Customer)

// 当没有传递要发送的角色时，默认传 agents
NSString* (^ checkRole)(NSString *) = ^(NSString* role){
    return role == nil ? @"agents" : role;
};

-(NSMutableDictionary *)labelAndStreams{
    _labelAndStreams = self.irtcSDK.labelAndStreams;
    return _labelAndStreams;
}

-(void)initWithServiceUrl:(NSString *)serviceUrl name:(NSString *)name password:(NSString *)password org:(NSString *)org mediaOptions:(NSDictionary *)mediaOptions onSuccess:(void (^)(ZcoModelUserInfo * _Nonnull))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
       //数据校验
       if (serviceUrl == nil || name == nil || password == nil || org == nil) {
           NSError *error = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:1003 userInfo:@{@"reason":@"请检查 url地址 登录名 密码 机构名 是否为空"}];
           onFailure(error);
           return;
       }
    self.mediaDic = mediaOptions;
       //设置音视频参数，nil则使用默认的音视频参数
       API *api = [API shared];
       [api loginWithUrl:serviceUrl name:name password:password
                     org:org complete:^(CallBackObject * _Nonnull result) {
           if (result.code == 200) {
               // 登录成功后初始化 ccs 和 irtc
               self.ccsClient = [[CCSClient alloc] init];
               self.irtcSDK = [[IRTCSDK alloc] init];
               self.irtcSDK.delegate = self;
               self.ccsClient.irtcSDK = self.irtcSDK;
               // 处理返回的数据
               self.zcoModelUserInfo = [[ZcoModelUserInfo alloc] initWithDictionary:[result.userInfo valueForKey:@"data"]];
               api.token = self.zcoModelUserInfo.accessToken;
               self.baseUrl = serviceUrl;
               // 登录成功后连接 CCS
               [self.ccsClient connectWithUrl:self.baseUrl andToken:api.token complete:^(CallBackObject * _Nonnull connectResult) {
                   if (connectResult.code == 200) {
                       self.ccsClient.ivcsSDKDelegate = self.delegate;
                       // 设置 ccs 消息的 delegate
                       MyCcsClientMessageDelegate *messageDelegate = [[MyCcsClientMessageDelegate alloc] init];
                       messageDelegate.ivcsCustomerDelegate = self.delegate;
                       self.ccsClient.messageDelegate = messageDelegate;
                       // 保存用户信息
                       self.ccsClient.userInfo = self.zcoModelUserInfo;
                       onSuccess(self.zcoModelUserInfo);
                   }else{
                       onFailure([IvcsCustomer sdkonFailureWithResponse:connectResult]);
                   }
               }];
           }else{
               NSLog(@"result.code=%ld,userInfo=%@,data=%@",(long)result.code,result.userInfo,result.data);
               if (result.code == 101) {
                   NSString *userInfoCode = [NSString stringWithFormat:@"%@", [result.userInfo objectForKey:@"code"]];
                   if ([userInfoCode isEqualToString:@"1103"]) {
//                 密码错误 Password mistake
                       NSError *amsError = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:1103 userInfo:@{@"message":@"用户登录密码错误"}];
                       onFailure(amsError);
                   }else if([userInfoCode isEqualToString:@"1104"]){
//                 用户失效 User is Disabled
                       NSError *amsError = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:1104 userInfo:@{@"message":@"用户账号失效无法登录"}];
                       onFailure(amsError);
                   }else if([userInfoCode isEqualToString:@"1101"]){
//                  网络请求鉴权失败
                       NSError *amsError = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:1101 userInfo:@{@"message":@"网络请求鉴权失败"}];
                       onFailure(amsError);
                   }else if ([userInfoCode isEqualToString:@"1001"]){
//                  Non-exist user     用户不存在
                       NSError *amsError = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:1001 userInfo:@{@"message":@"用户不存在"}];
                       onFailure(amsError);
                   }
               }else{
                   NSError *amsError = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:500 userInfo:@{@"message":@"api请求失败"}];
                   onFailure(amsError);
               }           }
       }];
}

//- (void)requestSession:(NSInteger)serviceId withFormId:(NSInteger) formId type:(NSString *)type onSuccess:(void (^)(ZcoModelSessionInfo * _Nonnull))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
-(void)requestSession:(NSInteger)serviceId withUserData:(NSDictionary *)userData type:(NSString *)type onSuccess:(void (^)(ZcoModelSessionInfo *sessionInfo))onSuccess
onFailure:(void (^)(NSError *error))onFailure{
    NSString *gender = [@"male" caseInsensitiveCompare:self.zcoModelUserInfo.tokenData.data.profile.gender] == NSOrderedSame ? @"先生" : @"女士";
    NSDictionary *requestParameter = @{
        @"media":@"video",
        @"userData":@{
            @"service":[userData objectForKey:@"service"],
            @"specifyAgent":@"",
            @"formId" : [userData objectForKey:@"formId"],
            @"gender" : gender,
            @"fullName" : self.zcoModelUserInfo.tokenData.data.profile.fullName,
            @"media" : type,
            @"clientInfo":@{
                @"type":@"ios"
            }
        },
        @"clientInfo":@{
            @"type":@"ios"
        }
    };
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient requestSession:requestParameter onSuccess:^(NSDictionary * _Nonnull result) {
            ZcoModelSessionInfo *sessionInfo = [[ZcoModelSessionInfo alloc] initWithDictionary:result];
            self.roomToken = sessionInfo.roomToken;
            onSuccess(sessionInfo);
        } onFailure:^(NSError * _Nonnull error) {
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}


//-(void)quitSession:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
-(void)quitSessionWithReason:(NSString *)reason onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError *error))onFailure{
    
    [self.irtcSDK leaveRoomSuccess:^{
        
    } onFailure:^(NSError * _Nonnull error) {
        
    }];
    
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        NSLog(@"IVCSSDK: ivcs quit session success.");
        [self.ccsClient quitSession:@{@"reason":reason} onSuccess:^{
            onSuccess();
        } onFailure:^(NSError * _Nonnull error) {
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        NSLog(@"IVCSSDK: ivcs quit session failure.");
        onFailure(error);
    }];
    
}

-(void)startVideoWithLabel:(NSString *)label callMediaType:(NSString *)type andRenderView:(IRTCMTLVideoView *)view onSuccess: (void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
#ifdef DEBUG
    // debug 模式下打印 irtc 日志
    IRTCSetMinDebugLogLevel(IRTCLoggingSeverityVerbose);
#endif
    NSLog(@"startVideo,irtc client,%@",self.irtcSDK);
    //MyLog(@"开始加入房间 token：%@" , self.roomToken);
    [self.irtcSDK joinRoomWithToken:self.roomToken onSuccess:^(IRTCConferenceInfo * _Nonnull info) {
        //MyLog(@"加入房间成功");
        
        self.mediaOptions = [[MediaStreamSettingOptions alloc] init];
        IRTCStreamConstraints *constraints = [[IRTCStreamConstraints alloc] init];
        constraints.audio = true;
        if ([type isEqualToString:@"video"] || [type isEqualToString:@""]) {
            constraints.video=[[IRTCVideoTrackConstraints alloc] init];
            if (self.mediaDic == nil) {
                constraints.video.resolution = CGSizeMake(640,480);
                constraints.video.frameRate = 15;
            }else{
                
                constraints.video.frameRate = [[self.mediaDic objectForKey:@"rate"] doubleValue];
                NSInteger height = [[self.mediaDic objectForKey:@"height"] integerValue];
                NSInteger width = [[self.mediaDic objectForKey:@"width"] integerValue];
                constraints.video.resolution = CGSizeMake(width, height);
            }
        
            constraints.video.devicePosition = AVCaptureDevicePositionFront;
        }
        self.mediaOptions.streamConstraints = constraints;
        IRTCPublishOptions* options=[[IRTCPublishOptions alloc] init];
        IRTCVideoCodecParameters *h264Parameters=[[IRTCVideoCodecParameters alloc] init];
        
        IRTCVideoEncodingParameters *videoParameters=[[IRTCVideoEncodingParameters alloc]init];
        videoParameters.codec=h264Parameters;
        h264Parameters.name = IRTCVideoCodecH264;

        if (self.mediaDic == nil) {
            videoParameters.maxBitrate = 1024;
        }else{
            NSString *videoRate = [self.mediaDic objectForKey:@"maxBitrate"];
            videoParameters.maxBitrate = [videoRate integerValue];
           
        }
        options.video=[NSArray arrayWithObjects:videoParameters, nil];
        IRTCAudioCodecParameters* pcmuParameters=[[IRTCAudioCodecParameters alloc] init];
        pcmuParameters.name = IRTCAudioCodecPcmu;
        IRTCAudioEncodingParameters *audioParameters=[[IRTCAudioEncodingParameters alloc] init];
        audioParameters.codec = pcmuParameters;
        options.audio=[NSArray arrayWithObjects:audioParameters, nil];
        self.mediaOptions.publishOptions = options;
   
        [self.irtcSDK publishLocalStreamToRoomWithStreamLabel:label mediaStreamSettingOptions:self.mediaOptions onSuccess:^(IRTCLocalStream * _Nonnull localStream, IRTCConferencePublication * _Nonnull publication) {
            self.localStreamLabel = label;
            [localStream attach:view];
            self.localStream = localStream;
            onSuccess();
        } onFailure:^(NSError * _Nonnull error) {
            //MyLog(@"pub 本地流失败：%@" , error);
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        //MyLog(@"加入房间失败：%@" , error);
        onFailure(error);
    }];
    
}

-(void)stopScreenShare{
    [self.irtcSDK stopScreenShare];
}
-(void)screenShare:(NSString *)label andRenderView:(IRTCMTLVideoView *)view onSuccess: (void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [self.irtcSDK publishScreenStreamToRoomWithStreamLabel:label mediaStreamSettingOptions:self.mediaOptions onSuccess:^(IRTCLocalStream * _Nonnull localStream, IRTCConferencePublication * _Nonnull publication) {
        onSuccess();
    } onFailure:onFailure];
}

-(void)renderStreamWithLabel:(NSString *)label renderView:(NSObject<IRTCVideoRenderer>*)renderer onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    IRTCRemoteStream *stream = [self.labelAndStreams valueForKey:label];
    [self.irtcSDK subscribeStreamWithLabel:label IRTCRemoteStream:stream onSuccess:^(IRTCConferenceSubscription * _Nonnull subscription) {
        [stream attach:renderer];
        dispatch_async(dispatch_get_main_queue(), ^{
            onSuccess();
        });
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}
- (void)attachStreamWithLabel:(NSString *)label renderView:(NSObject<IRTCVideoRenderer> *)view{
    if ([self.localStreamLabel isEqualToString:label]) {
        [self.localStream attach:view];
        return;
    }
    IRTCStream *stream = [self.labelAndStreams valueForKey:label];
    if(!stream){
        stream = [self.irtcSDK getRemoteStreamByVideoLabel:label];
    }
    [self.labelAndStreams setObject:stream forKey:label];
    [stream attach:view];
}
- (void)detachStreamWithLabel:(NSString *)label renderView:(NSObject<IRTCVideoRenderer> *)view{
    if (label == nil) {
        return;
    }
    if ([self.localStreamLabel isEqualToString:label]) {
        [self.localStream detach:view];
        return;
    }
    IRTCRemoteStream *stream = [self.labelAndStreams valueForKey:label];
    if(!stream){
        stream = [self.irtcSDK getRemoteStreamByVideoLabel:label];
    }
    [stream detach:view];
    [self.labelAndStreams removeObjectForKey:label];
}



- (void)switchCameraOnSuccess:(nullable void (^)(void))onSuccess onFailure:(nullable void (^)(NSError * _Nonnull))onFailure{
    [self.irtcSDK switchCameraOnSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}


-(void)muteWithMediaType:(NSString *)type onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    IRTCTrackKind kind;
    if ([type isEqualToString:@"video"]) {
        kind = IRTCTrackKindVideo;
    }else if([type isEqualToString:@"audio"]){
        kind = IRTCTrackKindAudio;
    }else{
        kind = IRTCTrackKindUnknown;
    }
    [self.irtcSDK muteWithMediaType:kind onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

-(void)unmuteWithMediaType:(NSString *)type onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    IRTCTrackKind kind;
    if ([type isEqualToString:@"video"]) {
        kind = IRTCTrackKindVideo;
    }else if([type isEqualToString:@"audio"]){
        kind = IRTCTrackKindAudio;
    }else{
        kind = IRTCTrackKindUnknown;
    }
    [self.irtcSDK unmuteWithMediaType:kind onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

-(void)shareResourceWithType:(NSString *)type resourceUrl:(NSString *)url resourceName:(NSString *)name toRoles:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    
    [self.ccsClient shareResourceWithType:type resourceUrl:url resourceName:name toRoles:roles onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
  
}

-(void)shareResourceWithType:(NSString *)type uploadUrl:(NSString *)uploadUrl fileData:(NSData *)fileData fileName:(NSString *)fileName mimeType:(NSString *)mimeType toRoles:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient shareResourceWithType:type uploadUrl:uploadUrl fileData:fileData fileName:fileName mimeType:mimeType toRoles:roles onSuccess:^{
            onSuccess();
        } onFailure:^(NSError * _Nonnull error) {
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

-(void)sendCustomMessage:(id)data toRoles:(NSString *__nullable)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient sendCustomMessage:data toRoles:checkRole(roles) onSuccess:^{
            if(onSuccess){
                onSuccess();
            }
        } onFailure:^(NSError * _Nonnull error) {
            if (onFailure) {
                onFailure(error);
            }
        }];
    } onFailure:^(NSError * _Nonnull error) {
        if (onFailure) {
            onFailure(error);
        }
    }];
}

-(void)sendFormData:(NSDictionary *)data toRoles:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient sendFormData:data toRoles:checkRole(roles) onSuccess:^{
            onSuccess();
        } onFailure:^(NSError * _Nonnull error) {
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

-(void)sendTextMessage:(NSString *)data toRoles:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    
    [self.ccsClient sendTextMessage:data toRoles:checkRole(roles) onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];

}
//-(void)sendMessageConfirmation:(ZcoModelConfirmData *)data toRoles:(NSString * __nullable)roles onSuccess:(void (^ __nullable)(void))onSuccess nFailure:(void (^ __nullable)(NSError *error))onFailure{
-(void)sendMessageConfirmation:(ZcoModelConfirmData *)data toRoles:(NSString * __nullable)roles onSuccess:(void (^ __nullable)(void))onSuccess onFailure:(void (^ __nullable)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient sendMessageConfirmation:data toRoles:checkRole(roles) onSuccess:^{
            if (onSuccess) {
                onSuccess();
            }
        } onFailure:^(NSError * _Nonnull error) {
            if (onFailure) {
                onFailure(error);
            }
        }];
    } onFailure:^(NSError * _Nonnull error) {
        if (onFailure) {
            onFailure(error);
        }
    }];
}

-(void)sendSnapshotMessage:(NSString *)imageUrl toRoles:(NSString * __nullable)roles onSuccess:(void (^__nullable)(void))onSuccess onFailure:(void (^ __nullable)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        NSDictionary *data = @{
            @"url":imageUrl,
            @"name":@"Signature",
            @"type":@"pic"
        };
        [self.ccsClient sendSnapshotMessage:data toRoles:checkRole(roles) onSuccess:^{
                if (onSuccess) {
                    onSuccess();
                }
            } onFailure:^(NSError * _Nonnull error) {
                if (onFailure) {
                    onFailure(error);
                }
            }];
        } onFailure:^(NSError * _Nonnull error) {
            if(onFailure){
                onFailure(error);
            }
        }];
}

- (void)sendPeerCMD:(ZcoModelCMD *)cmd to:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient sendPeerCMD:cmd to:checkRole(roles) onSuccess:onSuccess onFailure:onFailure];
        
        } onFailure:^(NSError * _Nonnull error) {
            if (onFailure) {
                onFailure(error);
            }
        }];
}

- (void)sendPeerCancel:(ZcoModelCMD *)cmd to:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        [self.ccsClient sendPeerCancel:cmd to:checkRole(roles) onSuccess:onSuccess onFailure:onFailure];
        } onFailure:^(NSError * _Nonnull error) {
            if (onFailure) {
                onFailure(error);
            }
        }];
}

- (void)sendPeerResponse:(ZcoModelCMD *)cmd to:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{

    [self.ccsClient sendPeerResponse:cmd to:checkRole(roles) onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];

}

-(void)locationResponse:(ZcoModelCMD *)locationInfo to:(NSString *__nullable)roles onSuccess:(void (^__nullable)(void))onSuccess onFailure:(void (^__nullable)(NSError * _Nonnull error))onFailure{
//    ZcoModelCMD *model =  [[ZcoModelCMD alloc]init];
//    model.data = @{
//        @"cmd":[dic objectForKey:@""],
//        @"":@""
//    };
    [self sendPeerResponse:locationInfo to:roles onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}
-(void)scanCodeAccept:(ZcoModelCMD *)scanCodeInfo to:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
//    ZcoModelCMD *model =  [[ZcoModelCMD alloc]init];
//    model.data = @{
//        @"status":CmdStatusAccepted
//    };
    [self sendPeerResponse:scanCodeInfo to:roles onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}
-(void)scanCodeRefuse:(ZcoModelCMD *)scanCodeInfo to:(NSString *)roles onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{

    [self sendPeerResponse:scanCodeInfo to:roles onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}
-(void)handwritingResponse:(ZcoModelCMD *)handwritingInfo to:(NSString *__nullable)roles onSuccess:(void (^__nullable)(void))onSuccess onFailure:(void (^__nullable)(NSError * _Nonnull error))onFailure{
    [self sendPeerResponse:handwritingInfo to:roles onSuccess:^{
        onSuccess();
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}
- (void)sendHandWritingMessage:(NSString * _Nullable)msg to:(NSString * _Nullable)roles{
    [CCSClient validateCcsClient:self.ccsClient onSuccess:^{
        if (msg == nil) {
            [self.ccsClient sendHandWritingMessage:@"{\"version\":\"3.4.0\",\"objects\":[]}" to:checkRole(roles)];
        }else{
            [self.ccsClient sendHandWritingMessage:msg to:checkRole(roles)];
        }
            
        } onFailure:^(NSError * _Nonnull error) {
            NSLog(@"sendHandWritingMessage failed: %@" , error);
        }];
}

-(void)sureUserInfoWithSessionId:(NSString *)sessionId url:(NSString *)url userInfo:(NSMutableDictionary *)userInfo onSuccess:(void (^)(void))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    API *api = [API shared];
    [api uploadUserInfoWithSessionId:sessionId url:url userInfo:userInfo onSuccess:^(NSString * _Nonnull formId) {
        NSString *message = [NSString stringWithFormat:@"formid=%@",formId];
        [self sendTextMessage:message toRoles:@"agents" onSuccess:^{
            onSuccess();
        } onFailure:^(NSError * _Nonnull error) {
            onFailure(error);
        }];
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

-(void)uploadFormDataWithSessionId:(NSString *)sessionId url:(NSString *)url parameter:(NSMutableDictionary *)parameter onSuccess:(void (^)(id _Nonnull))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    API *api = [API shared];
    [api uploadFormDataWithSessionId:sessionId url:url parameter:parameter onSuccess:^(id _Nonnull response) {
        onSuccess(response);
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

+(NSError *)sdkonFailureWithResponse:(CallBackObject *)result{
    NSError *error = [[NSError alloc] initWithDomain:ivcsSDKErrorDomain code:result.code userInfo:result.userInfo];
    return error;
}

- (void)refreshTicket{
    [self.ccsClient refreshTicket];
}

- (void)getScenarios:(void (^)(NSArray<ZcoModelSessionInfo *> *))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
    [[API shared] getScenarios:self.baseUrl onSuccess:onSuccess onFailure:onFailure];
}

-(void)getSnapShotImage:(void (^)(UIImage*))onSuccess onFailure:(void (^)(NSError*))onFailure{
    [self.irtcSDK getSnapShotImage:^(UIImage * _Nonnull image) {
        onSuccess(image);
    } onFailure:^(NSError * _Nonnull error) {
        onFailure(error);
    }];
}

#pragma mark IRTCSDKDelegate
- (void)onStreamAddWithLabel:(NSString *)label{
    if (self.delegate && [self.delegate respondsToSelector:@selector(onStreamAddWithLabel:)]) {
        [self.delegate onStreamAddWithLabel:label];
    }
}

- (void)onStreamRemoveWithLabel:(NSString *)label{
    if (self.delegate && [self.delegate respondsToSelector:@selector(onStreamRemoveWithLabel:)]) {
        [self.delegate onStreamRemoveWithLabel:label];
       }
}

//- (CGSize)getVideoSizeByVideoLable:(NSString *)videoLabel{
//    return [self.irtcSDK getVideoSizeByVideoLabel:videoLabel];
//}
//
//- (void)releaseAll{
//    // 释放 irtc 的占用的资源
//    if (self.irtcSDK != nil) {
////        [self.irtcSDK dealloc];
//    }
//}

//- (void)confirmCollect:(NSDictionary *)data onSuccess:(void (^)(CallBackObject *_Nonnull))onSuccess onFailure:(void (^)(NSError * _Nonnull))onFailure{
//    [[API shared] confirmCollect:data onSuccess:onSuccess onFailure:onFailure];
//}
//
///// 更新收集信息的表单
//-(void)updateCollectForm:(NSInteger) formId onSuccess:(void (^)(id))onSuccess
//               onFailure:(void (^)(NSError * _Nonnull))onFailure{
//    [[API shared] updateCollectForm:@{
//        @"formId":@(formId),
//        @"sessionId":self.ccsClient.sessionId
//    } onSuccess:onSuccess onFailure:onFailure];
//}

@end
